package org.example.config;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.example.filter.ValidCodeFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.*;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;


@SuppressWarnings({"all"})
@Configuration
public class WebSecurityConfig {
    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    @Autowired
    ValidCodeFilter validCodeFilter=new ValidCodeFilter();

    @Bean
    public UserDetailsService userDetailsService(){
        UserDetails user1= User.withUsername("admin").password(passwordEncoder().encode("123"))
                .roles("roles1","roles2","roles3").build();
        UserDetails user2= User.withUsername("user1").password(passwordEncoder().encode("123"))
                .roles("roles1").build();
        UserDetails user3= User.withUsername("user2").password(passwordEncoder().encode("123"))
                .roles("roles2").build();
        UserDetails user4= User.withUsername("user3").password(passwordEncoder().encode("123"))
                .roles("roles3").build();
        return new InMemoryUserDetailsManager(user1,user2,user3,user4);
    }

    public WebSecurityCustomizer webSecurityCustomizer(){
        //这些静态资源不拦截
        return (web -> web.ignoring().requestMatchers("/js/**","/css/**","/images/**"));
    }

    @Bean
    SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.addFilterBefore(validCodeFilter, UsernamePasswordAuthenticationFilter.class);
        //开启登录配置
        httpSecurity.authorizeHttpRequests()
                .requestMatchers("/","/index","/validcode").permitAll()      //允许直接访问的路径
                .requestMatchers("/menu1/**").hasRole("roles1")
                .requestMatchers("/menu2/**").hasRole("roles2")
                .requestMatchers("/menu3/**").hasRole("roles3")
                .anyRequest().authenticated()   //其他请求必须通过身份验证
                .and()
                .formLogin()   //开启表单验证
                .loginPage("/toLogin")   //自定义登录页路径
                .usernameParameter("username")  //自动以表单的用户名的name属性
                .passwordParameter("password")  //自动以表单的密码的name属性
                .loginProcessingUrl("/login")   //表单请求地址
                .failureUrl("/toLogin/error")    //登录失败跳转到
                .permitAll();
        httpSecurity.rememberMe();      //记住我
        httpSecurity.exceptionHandling().accessDeniedPage("/errorRole");    //没有权限时跳转页面
        httpSecurity.logout().logoutSuccessUrl("/index");   //注销后跳转的页面
        httpSecurity.csrf().disable();  //关闭csrf
        return  httpSecurity.build();
    }


//    @Bean
//    SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
//        httpSecurity.addFilterBefore(validCodeFilter, UsernamePasswordAuthenticationFilter.class);
//        //开启登录配置
//        httpSecurity.authorizeHttpRequests()
//                .requestMatchers("/","/index","/validcode").permitAll()      //允许直接访问的路径
//                .anyRequest().authenticated()   //其他请求必须通过身份验证
//                .and()
//                .formLogin()   //开启表单验证
//                .loginPage("/toLogin")   //自定义登录页路径
//                .usernameParameter("username")  //自动以表单的用户名的name属性
//                .passwordParameter("password")  //自动以表单的密码的name属性
//                .loginProcessingUrl("/login")   //表单请求地址
//                .successHandler(new AuthenticationSuccessHandler() {
//                    @Override
//                    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//                        response.setContentType("application/json;charset=utf-8");
//                        PrintWriter out=response.getWriter();
//                        String json="{\"status\":\"ok\",\"msg\":\"登陆成功\"}";
//                        out.write(json);
//                    }
//                })
//                .failureHandler(new AuthenticationFailureHandler() {
//                    @Override
//                    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
//                        response.setContentType("application/json;charset=utf-8");
//                        PrintWriter out=response.getWriter();
//                        String json="{\"status\":\"error\",\"msg\":\""+exception.getMessage()+"\"}";
//                        out.write(json);
//                    }
//                })
//                .permitAll();
//        httpSecurity.rememberMe();      //记住我
//        httpSecurity.logout().logoutSuccessHandler(new LogoutSuccessHandler() {
//            @Override
//            public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//                response.setContentType("application/json;charset=utf-8");
//                PrintWriter out=response.getWriter();
//                String json="{\"status\":\"ok\",\"msg\":\"退出登录\"}";
//                out.write(json);
//            }
//        });
//        httpSecurity.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() {
//            @Override
//            public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
//                response.setContentType("application/json;charset=utf-8");
//                PrintWriter out=response.getWriter();
//                String json="{\"status\":\"error\",\"msg\":\"权限不足\"}";
//                out.write(json);
//            }
//        });
//        httpSecurity.csrf().disable();  //关闭csrf
//        return  httpSecurity.build();
//    }
}
